/*************************************************************************
	> File Name: server.c
	> Author: Maureen 
	> Mail: 1437867946@qq.com 
	> Created Time: Wed 12 May 2021 02:46:31 PM CST
 ************************************************************************/

#include "head.h"

#define MAX 20
int port;
char *conf = "./footballd.conf"; //footballd.conf 服务端的配置文件

struct Map court; //足球场，中间那个正式场地
struct Bpoint ball; //球的位置
struct BallStatus ball_status; //球的状态
struct Score score; //比分
int repollfd, bepollfd; //从反应堆 sub_reactor

struct User *rteam, *bteam;

int main(int argc, char **argv) {
    //[1] 解析命令行参数
    int opt;
    while ((opt = getopt(argc, argv, "p:")) != -1) {
        switch (opt) {
            case 'p':
                port = atoi(optarg);
                break;
            default:
                fprintf(stderr, "Usage : %s -p port!\n", argv[0]);
                exit(1);
        }
    }

    //[2] 若没有命令行参数，从配置文件读取配置信息
    if (!port) port = atoi(get_value(conf, "port"));

    //[3] 创建udp socket
    int listener;
    if ((listener = socket_create_udp(port)) < 0) {
        perror("socket_create_udp");
        exit(1);
    }

    DBG(GREEN"INFO"NONE" : Server start on port : %d\n", port);

    //[4] 创建主从反应堆
    int epollfd; //epollfd - 主反应堆
    epollfd = epoll_create(1); 
    repollfd = epoll_create(1); //从反应堆
    bepollfd = epoll_create(1); //从反应堆

    if (epollfd < 0 || repollfd < 0 || bepollfd < 0) {
        perror("epoll_create");
        exit(1);
    }
    
    //开辟存储玩家信息的空间
    rteam = (struct User *)calloc(MAX, sizeof(struct User));
    bteam = (struct User *)calloc(MAX, sizeof(struct User));

    //[5] 创建消息队列
    struct task_queue redQueue;
    struct task_queue blueQueue;

    /*初始化任务队列*/
    task_queue_init(&redQueue, MAX, repollfd); 
    task_queue_init(&blueQueue, MAX, bepollfd);
    
    DBG(GREEN"INFO"NONE" : Resource calloc successfully.\n");
    
    struct epoll_event ev, events[MAX];
    ev.events = EPOLLIN; //等待接入
    ev.data.fd = listener; //关联到listener
    //listener注册到epollfd中
    if (epoll_ctl(epollfd, EPOLL_CTL_ADD, listener, &ev) < 0) {
        perror("epoll_ctl");
        exit(1);
    }
    DBG(GREEN"INFO"NONE" : Adding listener %d to Main Reactor.\n", listener);
    
    //[6]等待用户连接
    for (;;) { 
        DBG(YELLOW"Main Reactor"NONE" : Waiting for client.\n");
        int nfds = epoll_wait(epollfd, events, MAX, -1);//阻塞，等待连接，当有用户连接或出错才会返回
        if (nfds < 0) {
            perror("Main : epoll_wait");
            exit(1);
        } 
        for (int i = 0; i < nfds; i++) {
            if (events[i].data.fd == listener) {
                //accept 模拟TCP, 判断接收到报文是否符合要求  accept生成的新的fd看做是服务端和客户端的连接
                //add to sub_reactor
            } else {
                DBG(RED"ERROR"NONE" : Sth Error!\n");
                exit(1);
            }
        }
        
    }

    return 0; 
}
